package com.bidevalution.support.face;

import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Random;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;

/**
 * 
 * @author ffcs
 *
 */
public class AesCrypt {
	private static Logger log = Logger.getLogger(AesCrypt.class);
	private final static Charset CHARSET = Charset.forName("utf-8");
	private String appId;
	private String appKey;
	private byte[] aesKey;
	private Base64 base64 = new Base64();
	public AesCrypt(String appId,String appKey){
		this.appId=appId;
		this.appKey=appKey;
		this.aesKey=HexUtil.hexStr2ByteArr(this.appKey);
	}

	public AesCrypt(String appKey){
		this.appKey=appKey;
		this.aesKey=HexUtil.hexStr2ByteArr(this.appKey);
	}
	
	/**
	 * 数据加密
	 * @param data
	 * @param aesKey
	 * @return
	 */
	public String encrypt(String data) throws AesException{
		try {
			// 设置加密模式为AES的CBC模式
			ByteGroup byteCollector = new ByteGroup();
			Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
			SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
			IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16);
			cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
			
			byte[] unencrypted=data.getBytes(CHARSET);
			byteCollector.addBytes(unencrypted);
			// ... + pad: 使用自定义的填充方式对明文进行补位填充
			byte[] padBytes = PKCS7Encoder.encode(byteCollector.size());
			byteCollector.addBytes(padBytes);			
			// 加密
			byte[] encrypted = cipher.doFinal(byteCollector.toBytes());
			// 使用BASE64对加密后的字符串进行编码
			String base64Encrypted = base64.encodeToString(encrypted);
			return base64Encrypted;
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw new AesException(AesException.EncryptAESError);
		}
	}
	
	
	/**
	 * 对密文进行解密.
	 * 
	 * @param text 需要解密的密文
	 * @return 解密得到的明文
	 * @throws AesException aes解密失败
	 */
	public String decrypt(String text) throws AesException {
		byte[] original;
		try {
			// 设置解密模式为AES的CBC模式
			Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
			SecretKeySpec key_spec = new SecretKeySpec(aesKey, "AES");
			IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
			cipher.init(Cipher.DECRYPT_MODE, key_spec, iv);

			// 使用BASE64对密文进行解码
			byte[] encrypted = Base64.decodeBase64(text);

			// 解密
			original = cipher.doFinal(encrypted);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw new AesException(AesException.DecryptAESError);
		}

		String jsonContent;
		try {
			// 去除补位字符
			byte[] bytes = PKCS7Encoder.decode(original);
			jsonContent = new String(bytes, CHARSET);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw new AesException(AesException.IllegalBuffer);
		}
		return jsonContent;
	}
	

}
